package main

import (
	"fmt"
	"math/rand"
	"sort"
)

// Usb 声明定义一个接口
//声明了两个没有实现的方法
type Usb interface {
	Start()
	Stop()
}
type Phone struct {
	Name string
}
type Caramel struct {
	Name string
}

// Start 让Phone实现Usb接口方法
func (p Phone) Start() {
	fmt.Println("手机开始工作..")
}
func (p Phone) Stop() {
	fmt.Println("手机停止工作...")
}

// Start 让Caramel实现Usb接口方法
func (c Caramel) Start() {
	fmt.Println("相机开始工作..")
}
func (c Caramel) Stop() {
	fmt.Println("相机停止工作...")
}

func (p Phone) Call() {
	fmt.Println("手机开始打电话...")
}

// Computer 计算机
type Computer struct {
}

// Working 编写一个方法Working方法，接受一个Usb接口类型变量
// 只要实现了Usb接口（所谓实现了Usb接口，就是指实现了Usb接口声明所有方法）
func (c Computer) Working(usb Usb) {
	// 通过usb接口来调用Start和Stop方法
	usb.Start()
	// 添加类型断言
	if phone, ok := usb.(Phone); ok {
		phone.Call()
	}
	usb.Stop()
}

/**
调用sort方法实现接口
*/

// Hero 1、声明Hero结构体
type Hero struct {
	Name string
	Age  int
}

// HeroSlice 2、声明一个Hero结构体切片类型
type HeroSlice []Hero

// Len 3、实现Interface接口
func (hs HeroSlice) Len() int {
	return len(hs)
}

// Less 方法决定使用什么标准进行排序
// 按照年龄从小到大进行排序
func (hs HeroSlice) Less(i, j int) bool {
	return hs[i].Age < hs[j].Age
	// 修改成对Name排序
	//return hs[i].Name < hs[j].Name
}
func (hs HeroSlice) Swap(i, j int) {
	// 完成交换
	//temp := hs[i]
	//hs[i] = hs[j]
	//hs[j] = temp
	hs[i], hs[j] = hs[j], hs[i]
}

// Point 类型断言
type Point struct {
	x int
	y int
}

func main() {
	// test 类型断言
	var a interface{}
	var point = Point{1, 3}
	a = point
	var b Point
	// b = a 不可以，原因a是空接口类型，不能直接赋值，需要将a进行类型断言，尝试转换为Point
	b = a.(Point)
	fmt.Println(b)

	// test 类型断言（带检测）
	var x interface{}
	var b2 float32 = 1.14
	x = b2
	y, ok := x.(float32)
	if ok {
		fmt.Println("success")
		fmt.Println(y)
	} else {
		fmt.Println("fail")
	}
	fmt.Println("继续执行...")

	// 声明一个HeroSlice切片，并循环赋值
	var heroes HeroSlice
	for i := 0; i < 10; i++ {
		hero := Hero{
			Name: fmt.Sprintf("英雄%d", rand.Intn(100)),
			Age:  rand.Intn(100),
		}
		heroes = append(heroes, hero)
	}
	// 未排序前
	for _, v := range heroes {
		fmt.Println(v)
	}
	// 排序后
	sort.Sort(heroes)
	for _, v := range heroes {
		fmt.Println("===>", v)
	}
	// 将hero append到heroes切片

	// 测试
	var usbArr [3]Usb
	usbArr[0] = Phone{Name: "iphone"}
	usbArr[1] = Phone{Name: "huawei"}
	usbArr[2] = Caramel{Name: "佳能"}
	//fmt.Println(usbArr)
	computer := Computer{}

	for _, v := range usbArr {
		computer.Working(v)
	}

	/*	computer := Computer{}
		phone := Phone{}
		caramel := Caramel{}
		computer.Working(phone)
		computer.Working(caramel)
	*/
}
